package com.gome.boot.config.elasticsearch;

import com.gome.boot.common.util.StringToUtils;
import com.gome.boot.config.elasticsearch.cluster.BaseMultiClusterElasticsearchConfig;
import com.gome.boot.config.elasticsearch.standalone.BaseStandaloneElasticsearchConfig;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;
import org.springframework.data.elasticsearch.core.DefaultEntityMapper;
import org.springframework.data.elasticsearch.core.EntityMapper;

import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;

/**
 * ES服务基础配置.
 * <br/>多集群时，应用请实现多集群基础配置:
 * @see BaseMultiClusterElasticsearchConfig
 * <br/>单集群或单实例时，应用请实现单集群或单实例基础配置:
 * @see BaseStandaloneElasticsearchConfig
 *
 * @author baoxiufeng
 */
public abstract class BaseElasticsearchConfig {

    protected static final String KEY_ES_CLUSTER_NAME = "es.cluster.name";
    protected static final  String KEY_ES_CLUSTER_NOES = "es.cluster.nodes";

    @Autowired
    protected Environment env;

    /**
     * 根据集群名称和集群节点列表创建集群客户端.
     *
     * @param clusterName 集群名称
     * @param clusterNodes 集群节点列表
     * @return 集群操作客户端
     * @throws Exception 异常
     */
    protected Client createClient(String clusterName, String clusterNodes) throws Exception {
        Settings esSettings = Settings.settingsBuilder()
                .put("cluster.name", clusterName)
                .build();
        List<String> values = StringToUtils.stringToList(clusterNodes);
        List<InetSocketTransportAddress> addresses = new ArrayList<InetSocketTransportAddress>(values.size());
        Object[] hostAndPort = null;
        for (String value : values) {
            hostAndPort = StringToUtils.stringToArray(value, ":", String.class, Integer.class);
            if (hostAndPort.length == 2) {
                addresses.add(new InetSocketTransportAddress(InetAddress.getByName((String) hostAndPort[0]), (Integer) hostAndPort[1]));
            }
        }
        return TransportClient.builder()
                .settings(esSettings)
                .build()
                .addTransportAddresses(addresses.toArray(new InetSocketTransportAddress[addresses.size()]));
    }

    @Bean
    public EntityMapper entityMapper() {
        return new DefaultEntityMapper();
    }
}
